#include "mainwidget.h"
#include "./ui_mainwidget.h"
#include "toast.h"

#include <QPushButton>
#include <QIcon>
#include <QHBoxLayout>
#include <QVBoxLayout>

#include "model/datacenter.h"
#include "sessionfriendarea.h"
#include "debug.h"
#include "messageshowarea.h"
#include "messageeditarea.h"
#include "selfinfowidget.h"
#include "sessiondetailwidget.h"
#include "groupsessiondetailwidget.h"
#include "addfrienddialog.h"

#include "model/data.h"

MainWidget* MainWidget::instance = nullptr;

MainWidget::MainWidget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::MainWidget)
{
    ui->setupUi(this);

    this->setWindowTitle("outlier");
    this->setWindowIcon(QIcon(":/resource/image/logo.png"));

    // 初始化界面
    initMainWindow();
    initWindowLeft();
    initWindowMid();
    initWindowRight();

    // 注册信号槽
    initSingalSlot();
}

MainWidget::~MainWidget()
{
    delete ui;
}

MainWidget* MainWidget::getInstance()
{
    if(!instance) {
        instance = new MainWidget();
        return instance;
    }
    return instance;
}


void MainWidget::initMainWindow()
{
    QHBoxLayout* layout = new QHBoxLayout();
    layout->setSpacing(0);
    layout->setContentsMargins(0, 0, 0, 0);
    this->setLayout(layout);

    windowLeft = new QWidget();
    windowMid = new QWidget();
    windowRight = new QWidget();

    windowLeft->setObjectName("windowLeft");
    windowMid->setObjectName("windowMid");
    windowRight->setObjectName("windowRight");

    // left mid 指定宽带固定值
    windowLeft->setFixedWidth(60);
    windowMid->setFixedWidth(310);
    // right 指定最小值
    windowRight->setMinimumWidth(800);

    layout->addWidget(windowLeft);
    layout->addWidget(windowMid);
    layout->addWidget(windowRight);

    QString style = "#windowLeft { background-color: rgb(46, 46, 46); }"
                    "#windowMid { background-color: rgb(247, 247, 247); } "
                    "#windowRight { background-color: rgb(245, 245, 245); }";
    this->setStyleSheet(style);
}

void MainWidget::initWindowLeft()
{
    QVBoxLayout* layout = new QVBoxLayout();
    layout->setSpacing(20);
    layout->setContentsMargins(0, 35, 0, 0);    // 左上右下
    windowLeft->setLayout(layout);

    auto makeButton = [&](QSize qSize, const QString& img){
        QPushButton* btn = new QPushButton();
        btn->setFixedSize(45, 45);
        btn->setIconSize(qSize);
        btn->setIcon(QIcon(img));
        btn->setStyleSheet("QPushButton { background-color: transparent;}");
        layout->addWidget(btn, 1, Qt::AlignTop | Qt::AlignHCenter);
        return btn;
    };

    // 初始化用户头像 tab按钮
    userAvatar   = makeButton({40, 40}, ":/resource/image/girl.jpg");
    // userAvatar->setIcon(QIcon());
    sessionTabBtn= makeButton({28, 28}, ":/resource/image/session_active.png");
    friendTabBtn = makeButton({28, 28}, ":/resource/image/friend_inactive.png");
    applyTabBtn  = makeButton({28, 28}, ":/resource/image/apply_inactive.png");

    layout->addStretch(20);
}

void MainWidget::initWindowMid()
{
    QGridLayout* layout = new QGridLayout();
    layout->setContentsMargins(0, 15, 0, 0);
    layout->setVerticalSpacing(10);
    layout->setHorizontalSpacing(0);
    windowMid->setLayout(layout);
    windowMid->setStyleSheet("QWidget { border: none; }");

    // 搜素框
    searchEdit = new QLineEdit();
    searchEdit->setFixedHeight(25);
    searchEdit->setPlaceholderText("搜索");   // 预显示
    searchEdit->setStyleSheet("QLineEdit { border-radius: 5px; background-color: rgb(226, 226, 226); padding-left: 5px; }");

    // 添加好友按钮
    addFriendBtn = new QPushButton();
    addFriendBtn->setFixedSize(25, 25);
    addFriendBtn->setIcon(QIcon(":/resource/image/cross.png"));
    QString style = QString("QPushButton { border-radius: 5px; background-color: rgb(226, 226, 226) }");
    style += "QPushButton:pressed { background-color: rgb(240, 240, 240); }";
    addFriendBtn->setStyleSheet(style);

    sessionFriendArea = new SessionFriendArea();

    // 使用空白Widget填充, 仅改变搜素框一行的边距布局
    QWidget* spacer1 = new QWidget();
    QWidget* spacer2 = new QWidget();
    QWidget* spacer3 = new QWidget();
    spacer1->setFixedWidth(10);
    spacer2->setFixedWidth(10);
    spacer3->setFixedWidth(10);

    layout->addWidget(spacer1, 0, 0);
    layout->addWidget(searchEdit, 0, 1);
    layout->addWidget(spacer2, 0, 2);
    layout->addWidget(addFriendBtn, 0, 3);
    layout->addWidget(spacer3, 0, 4);
    layout->addWidget(sessionFriendArea, 1, 0, 1, 5);   // 横跨1行5列
}

void MainWidget::initWindowRight()
{
    // 1. 创建右侧窗口布局管理器
    QVBoxLayout* layout = new QVBoxLayout();
    layout->setSpacing(0);
    layout->setContentsMargins(0, 0, 0, 0);
    layout->setAlignment(Qt::AlignTop);
    windowRight->setLayout(layout);
    // windowRight->setStyleSheet("QWidget { background-color: rgb(245, 245, 245); }");

    // 2. 顶部标题栏
    QWidget* titleWidget = new QWidget();
    titleWidget->setFixedHeight(62);
    titleWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    titleWidget->setObjectName("titleWidget");
    titleWidget->setStyleSheet("#titleWidget { border-bottom: 1px solid rgb(230, 230, 230); "
                               "border-left: 1px solid rgb(230, 230, 230); }");
    layout->addWidget(titleWidget);

    // 3. 标题栏里再创建一个布局管理器, 管理文本框和更多选项按钮
    QHBoxLayout* titleLayout = new QHBoxLayout();
    titleLayout->setSpacing(0);
    titleLayout->setContentsMargins(15, 0, 10, 0);
    titleWidget->setLayout(titleLayout);

    sessionTitle = new QLabel();
    sessionTitle->setStyleSheet("QLabel { font-size: 22px; border-bottom: 1px solid rgb(230, 230, 230); }");
#if TEST_UI
    sessionTitle->setText("这是测试标题");
#endif
    titleLayout->addWidget(sessionTitle);     // 将标题文本框添加到标题栏的布局管理器

    sessionDetailBtn = new QPushButton();
    sessionDetailBtn->setFixedSize(30, 30);
    sessionDetailBtn->setIconSize(QSize(30, 30));
    sessionDetailBtn->setIcon(QIcon(":/resource/image/more.png"));
    sessionDetailBtn->setStyleSheet("QPushButton { background-color: rgb(245, 245, 245); border: none;}"
                               "QPushButton:pressed { background-color: rgb(222, 222,223); }");

    titleLayout->addWidget(sessionDetailBtn);  // 将按钮添加到标题栏的布局管理器

    // 4. 创建消息展示区
    messageShowArea = new MessageShowArea();
    layout->addWidget(messageShowArea);

    // 5. 创建消息编辑区
    messageEditArea = new MessageEditArea();
    layout->addWidget(messageEditArea, 0, Qt::AlignBottom);
}

// 处理按钮标签页图标切换
void MainWidget::initSingalSlot()
{
    model::DataCenter* dataCenter = model::DataCenter::getInstance();

    ///////////////// 处理标签页按钮状态切换
    connect(sessionTabBtn, &QPushButton::clicked, this, &MainWidget::switchTabToSession);
    connect(friendTabBtn, &QPushButton::clicked, this, &MainWidget::switchTabToFriend);
    connect(applyTabBtn, &QPushButton::clicked, this, &MainWidget::switchTabToApply);

    ///////////////// 点击个人头像, 弹出个人信息卡片
    connect(userAvatar, &QPushButton::clicked, this, [=](){
        SelfInfoWidget* selfInfoWidget = new SelfInfoWidget(this);
        selfInfoWidget->exec();         // 弹出模态对话框
        // selfInfoWidget->show();      // 非模态
    });

    ///////////////// 添加好友按钮信号处理
    connect(addFriendBtn, &QPushButton::clicked, this, [=](){
        AddFriendDialog* addFriendDialog = new AddFriendDialog(this);
        addFriendDialog->exec();
    });

    ///////////////// 会话详情页面信号处理
    connect(sessionDetailBtn, &QPushButton::clicked, this, [=](){
// #if TEST_GROUP_SESSION_DETAIL
//         bool isSingleChat = false;
// #else
//         bool isSingleChat = true;
// #endif

        model::ChatSessionInfo* chatSessionInfo = dataCenter->getChatSessionInfoBySessionId(dataCenter->getCurrentChatSessionId());
        if(!chatSessionInfo) {
            LOG(LL_ERROR, "错误行为, 当前会话已失效!");
            return;
        }

        if(chatSessionInfo->userId != "") {
            model::UserInfo* userInfo = dataCenter->getFriendByUserId(chatSessionInfo->userId);
            if(!userInfo) {
                LOG(LL_ERROR, "错误行为, 当前会话的用户不在好友列表中");
                return;
            }
            SessionDetailWidget* sessionDetailWidget = new SessionDetailWidget(this, userInfo);
            sessionDetailWidget->exec();         // 弹出模态对话框
        } else {
            GroupSessionDetailWidget* groupSessionDetailWidget = new GroupSessionDetailWidget(this);
            groupSessionDetailWidget->exec();
        }
    });


    ///////////////// 获取用户的个人信息
    /// getSelfInfoAsync 异步网络通信获取个人信息, 获取完成后内部会通知 getSelfInfoDone
    connect(dataCenter, &model::DataCenter::getSelfInfoDone, this, [=](){
        model::UserInfo* selfInfo = dataCenter->getSelfInfo();
        userAvatar->setIcon(selfInfo->avatar);      // 设置用户头像
    });
    dataCenter->getSelfInfoAsync();


    ///////////////// 获取好友列表
    loadFriendList();

    ///////////////// 获取会话列表
    loadSessionList();

    ///////////////// 获取申请好友列表
    loadApplyList();

    ///////////////// 处理修改头像
    connect(dataCenter, &model::DataCenter::changeAvatarDone, this, [=](){
        userAvatar->setIcon(dataCenter->getSelfInfo()->avatar);
    });

    ///////////////// 处理删除好友
    connect(dataCenter, &model::DataCenter::deleteFriendDone, this, [=](){
        //到这一步, 数据已经处理完了, 所以需要更新界面
        this->updateFriendList();
        this->updateSessionList();
        int idx = dataCenter->getCurChatSessionInfoIndex();
        if(idx != -1) {
            sessionFriendArea->clickItem(idx);
        }
        LOG(LL_DEBUG, "删除好友完成");
    });
    connect(dataCenter, &model::DataCenter::clearCurrentChatSession, this, [=](){
        // 清空消息展示区
        sessionTitle->setText("");
        messageShowArea->clear();
        dataCenter->setCurrentChatSessionId("");
        LOG(LL_DEBUG, "清空会话完成");
    });

    ///////////////// 添加好友申请处理
    connect(dataCenter, &model::DataCenter::addFriendApplyDone, this, [=](){
        Toast::showMessage("好友申请发送成功");
    });
    connect(dataCenter, &model::DataCenter::receiveFriendApplyDone, this, [=](){
        this->updateApplyList();
        Toast::showMessage("收到新的好友申请");
    });
    connect(dataCenter, &model::DataCenter::friendApplyProcessDone, this, [=](bool agree){
        if(agree) {
            this->updateFriendList();
            this->updateApplyList();
            Toast::showMessage("好友添加成功");
        } else {
            this->updateApplyList();
            Toast::showMessage("好友拒绝你的申请");
        }
    });
    connect(dataCenter, &model::DataCenter::receiveFriendProcessDone, this, [=](const QString& nickname, bool agree){
        if(agree) {
            this->updateFriendList();
            Toast::showMessage(nickname + " 同意了你的好友申请");
        } else {
            Toast::showMessage(nickname + " 拒绝了你的好友申请");
        }
    });

    ///////////////// 创建新群聊信号响应
    connect(dataCenter, &model::DataCenter::createGroupChatSessionDone, this, [=](){
        Toast::showMessage("群聊创建成功");
    });

    ///////////////// 创建会话后推送数据处理
    connect(dataCenter, &model::DataCenter::receiveSessionCreateDone, this, [=](){
        this->updateSessionList();
        Toast::showMessage("你被拉入新的群聊");
    });
}

void MainWidget::switchTabToSession()
{
    activeTab = ActiveTab::SESSION_LIST;
    sessionTabBtn->setIcon(QIcon(":/resource/image/session_active.png"));
    friendTabBtn->setIcon(QIcon(":/resource/image/friend_inactive.png"));
    applyTabBtn->setIcon(QIcon(":/resource/image/apply_inactive.png"));
    loadSessionList();
}

void MainWidget::switchTabToFriend()
{
    activeTab = ActiveTab::FRIEND_LIST;
    sessionTabBtn->setIcon(QIcon(":/resource/image/session_inactive.png"));
    friendTabBtn->setIcon(QIcon(":/resource/image/friend_active.png"));
    applyTabBtn->setIcon(QIcon(":/resource/image/apply_inactive.png"));
    loadFriendList();
}

void MainWidget::switchTabToApply()
{
    activeTab = ActiveTab::APPLY_LIST ;
    sessionTabBtn->setIcon(QIcon(":/resource/image/session_inactive.png"));
    friendTabBtn->setIcon(QIcon(":/resource/image/friend_inactive.png"));
    applyTabBtn->setIcon(QIcon(":/resource/image/apply_active.png"));
    loadApplyList();
}

void MainWidget::loadSessionList()
{
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    if(dataCenter->getChatSessionList()) {
        // 已经从服务器加载过数据了, 直接通过数据中心获取
        updateSessionList();
    } else {
        // 网络通信从服务器获取数据
        connect(dataCenter, &model::DataCenter::getChatSessionListDone, this, &MainWidget::updateSessionList, Qt::UniqueConnection);
        dataCenter->getChatSessionListAsync();
    }
}

void MainWidget::loadFriendList()
{
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    if(dataCenter->getFriendList()) {
        // 已经从服务器加载过数据了, 直接通过数据中心获取
        updateFriendList();
    } else {
        // 网络通信从服务器获取数据
        connect(dataCenter, &model::DataCenter::getFriendListDone, this, &MainWidget::updateFriendList, Qt::UniqueConnection);
        dataCenter->getFriendListAsync();
    }
}

void MainWidget::loadApplyList()
{
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    if(dataCenter->getApplyList()) {
        // 已经从服务器加载过数据了, 直接通过数据中心获取
        updateApplyList();
    } else {
        // 网络通信从服务器获取数据
        connect(dataCenter, &model::DataCenter::getApplyListDone, this, &MainWidget::updateApplyList, Qt::UniqueConnection);
        dataCenter->getApplyListAsync();
    }
}

void MainWidget::updateSessionList()
{
    if(activeTab != ActiveTab::SESSION_LIST) {
        return;
    }

    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    const QList<model::ChatSessionInfo>* sessionList = dataCenter->getChatSessionList();
    std::list<int>* listOrder = dataCenter->getDisplayOrder();

    // 清空原有好友会话窗口
    sessionFriendArea->clear();

    for(const int& idx : *listOrder) {
        const auto& s = (*sessionList)[idx];

        if (s.lastMessage.messageType == model::MessageType::TEXT_TYPE) {
            sessionFriendArea->addItem(ItemType::SessionItemType, s.chatSessionId, s.avatar, s.chatSessionName, s.lastMessage.content);
        } else if(s.lastMessage.messageType == model::MessageType::FILE_TYPE) {
            sessionFriendArea->addItem(ItemType::SessionItemType, s.chatSessionId, s.avatar, s.chatSessionName, "[文件]");
        } else if(s.lastMessage.messageType == model::MessageType::IMAGE_TYPE) {
            sessionFriendArea->addItem(ItemType::SessionItemType, s.chatSessionId, s.avatar, s.chatSessionName, "[图片]");
        } else if(s.lastMessage.messageType == model::MessageType::SPEECH_TYPE) {
            sessionFriendArea->addItem(ItemType::SessionItemType, s.chatSessionId, s.avatar, s.chatSessionName, "[语音]");
        } else {
            LOG(LL_ERROR, "错误的数据类型, messageType : {}", s.lastMessage.messageType);
        }
    }

    // 未选中任何会话时, 禁用发送按钮
    messageEditArea->getSendBtn()->setEnabled(false);
}

void MainWidget::updateFriendList()
{
    // 过滤不包含该功能的标签页
    if(activeTab != ActiveTab::FRIEND_LIST) {
        return;
    }

    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    const QList<model::UserInfo>* friendList = dataCenter->getFriendList();

    // 清空原有好友会话窗口()
    sessionFriendArea->clear();

    for(const auto& f : *friendList) {
        sessionFriendArea->addItem(ItemType::FriendItemType, f.userId, f.avatar, f.nickname, f.description);
    }
}

void MainWidget::updateApplyList()
{
    if(activeTab != ActiveTab::APPLY_LIST) {
        return;
    }

    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    const QList<model::UserInfo>* applyList = dataCenter->getApplyList();

    // 清空原有好友会话窗口
    sessionFriendArea->clear();

    for(const auto& a: *applyList) {
        sessionFriendArea->addItem(ItemType::ApplyItemType, a.userId, a.avatar, a.nickname, "");
    }
}

void MainWidget::updateRecentMessageList(const QString& chatSessionId)
{
    model::DataCenter* dataCenter = model::DataCenter::getInstance();

    if(dataCenter->getCurrentChatSessionId() == chatSessionId) {
        return;
    }

    const QList<Message>* recentMessageList = dataCenter->getRecentMessageList(chatSessionId);

    // 清空原选定好友的消息会话
    messageShowArea->clear();

    for(int i = 0; i < recentMessageList->size(); ++i) {
        const Message& msg = recentMessageList->at(i);
        messageShowArea->addMessage(msg.sender.userId != dataCenter->getSelfInfo()->userId, msg);
    }

    // 设置会话标题
    model::ChatSessionInfo* chatSessionInfo = dataCenter->getChatSessionInfoBySessionId(chatSessionId);
    if(chatSessionInfo) {
        sessionTitle->setText(chatSessionInfo->chatSessionName);
    } else {
        LOG(LL_ERROR, "{}的会话不存在, chatSessionId: {}", chatSessionInfo->chatSessionName, chatSessionId);
    }

    // 更新当前会话记录
    dataCenter->setCurrentChatSessionId(chatSessionId);

    // 还原发送按钮
    messageEditArea->getSendBtn()->setEnabled(true);

    // 将滚动条置底
    messageShowArea->scrollToEndLater();
}

void MainWidget::loadRecentMessages(const QString& chatSessionId)
{
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    if(dataCenter->getRecentMessageList(chatSessionId)) {
        // 已经从服务器加载过数据了, 直接通过数据中心获取
        updateRecentMessageList(chatSessionId);
    } else {
        // 网络通信从服务器获取数据
        connect(dataCenter, &model::DataCenter::getRecentMessageListDone, this, &MainWidget::updateRecentMessageList, Qt::UniqueConnection);
        dataCenter->getRecentMessageListAsync(chatSessionId);
    }
}

void MainWidget::switchToSession(const QString &userId)
{
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    model::ChatSessionInfo* chatSessionInfo = dataCenter->getChatSessionInfoByUserId(userId);
    if(!chatSessionInfo) {
        return;
    }

    // 会话置顶
    dataCenter->chatSessionInfoToTop(chatSessionInfo);

    // 切换会话窗口
    switchTabToSession();

    // 将该用户对应的会话设置为点击状态
    sessionFriendArea->clickItem(0);

    // 滚动条置顶
    sessionFriendArea->scrollToBeginLater();
}

MessageShowArea* MainWidget::getMessageShowArea()
{
    return messageShowArea;
}

